package com.stars.easyms.rest.autoconfigure;

import com.stars.easyms.monitor.handler.EasyMsRequestMappingHandlerMapping;
import com.stars.easyms.redis.template.EasyMsRedisTemplate;
import com.stars.easyms.rest.initializer.EasyMsRestInitializer;
import com.stars.easyms.rest.manager.EasyMsRestRedisManager;
import com.stars.easyms.rest.pointcut.EasyMsExceptionHandlerPointcutAdvisor;
import com.stars.easyms.rest.pointcut.EasyMsRequestMappingPointcutAdvisor;
import com.stars.easyms.rest.properties.EasyMsRestProperties;
import com.stars.easyms.rest.filter.EasyMsRestFilter;
import com.stars.easyms.base.util.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * Rest配置类
 *
 * @author guoguifang
 * @date 2018-10-12 11:24
 * @since 1.0.0
 */
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(EasyMsRestProperties.class)
public class EasyMsRestAutoConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(EasyMsRestAutoConfiguration.class);

    private final EasyMsRestProperties easyMsRestProperties;

    private final EasyMsRequestMappingHandlerMapping easyMsRestHandlerMapping;

    public EasyMsRestAutoConfiguration(ConfigurableApplicationContext applicationContext, EasyMsRestProperties easyMsRestProperties) {
        this.easyMsRestProperties = easyMsRestProperties;
        this.easyMsRestHandlerMapping = new EasyMsRequestMappingHandlerMapping(applicationContext);
        this.easyMsRestHandlerMapping.setOrder(this.easyMsRestHandlerMapping.getOrder() - 1);
        BeanUtil.registerSingleton(applicationContext, "easyMsRestHandlerMapping", this.easyMsRestHandlerMapping);
    }

    @Bean(initMethod = "init")
    public EasyMsRestInitializer easyMsRestInitializer() {
        return new EasyMsRestInitializer(easyMsRestProperties, easyMsRestHandlerMapping);
    }

    @Bean
    public FilterRegistrationBean easyMsRestFilterRegistration() {
        FilterRegistrationBean<EasyMsRestFilter> filterRegistration = new FilterRegistrationBean<>();
        if (easyMsRestProperties.getUrlPatterns() == null || easyMsRestProperties.getUrlPatterns().isEmpty()) {
            easyMsRestProperties.setUrlPatterns(Collections.singleton("/*"));
        }
        filterRegistration.addUrlPatterns(easyMsRestProperties.getUrlPatterns().toArray(new String[0]));
        filterRegistration.setFilter(new EasyMsRestFilter(easyMsRestProperties));
        filterRegistration.setOrder(easyMsRestProperties.getOrder());
        logger.info("[Rest Starter] register with urlPatterns: {}.", easyMsRestProperties.getUrlPatterns());
        return filterRegistration;
    }

    @Bean
    public EasyMsRequestMappingPointcutAdvisor easyMsRequestMappingPointcutAdvisor() {
        return new EasyMsRequestMappingPointcutAdvisor(easyMsRestProperties);
    }

    @Bean
    public EasyMsExceptionHandlerPointcutAdvisor easyMsExceptionHandlerPointcutAdvisor() {
        return new EasyMsExceptionHandlerPointcutAdvisor();
    }

    @Configuration
    @ConditionalOnClass(EasyMsRedisTemplate.class)
    public static class EasyMsRestRedisManagerAutoConfiguration {

        @Bean
        public EasyMsRestRedisManager easyMsRestRedisManager() {
            return new EasyMsRestRedisManager();
        }
    }

}
